/*
 * display.c
 *
 *  Created on: Sep 14, 2013
 *      Author: Ken Arok
 */

#include "display_hal.h"
#include "timers_hw.h"
#include "display.h"



/* Function of turn off LCD back light. */
static TimerFuncVoid_t _funcTurnBackLightOff;
/* Function of turn on LCD back light. */
static TimerFuncVoid_t _funcTurnBackLightOn;
/* Timer for LCD Back Light OFF. */
static volatile uint32_t *_tmrBackLightOff = NULL;
/* Timer for LCD Back Light On. */
static volatile uint32_t *_tmrBackLightOn = NULL;

static uint8_t _display_flag_on = 0, _display_flag_off = 0;

/** \brief Turn back light LCD ON.
 *
 *  \param _tmr	Pointer to obtained timer.
 *
 */
static void prvTurnOnBackLight(void *_tmr);

/** \brief Turn back light LCD OFF.
 *
 *  \param _tmr	Pointer to obtained timer.
 *
 */
static void prvTurnOffBackLight(void *_tmr);

/* ----------------------------------------------------------------------------------- */


void vInitDisplay(void)
{
	display_init();
}


void vSetPositionDisplay(uint8_t _row, uint8_t _col)
{
	display_set_pos(_row, _col);
}


void vPutDisplay(uint8_t _row, uint8_t _col, const char _char)
{
	display_put(_row, _col, _char);
}


void vPrintDisplay(uint8_t _row, uint8_t _col, const char *_string)
{
	display_print(_row, _col, _string);
}


void vClearDisplay(void)
{
	display_clear();
}


void vControlDisplay(const uint8_t _ctrl)
{
	display_control(_ctrl);
}

void vTurnBackLightDisplay(uint8_t _on_off, uint32_t _val)
{
	switch(_on_off) {
		case iON:
			/* Turn LCD Back Light ON via Timer. */
			if(_tmrBackLightOn == NULL) {
				/* Obtain Timer. */
				_tmrBackLightOn = vTimer500msTake();
			}

			if(_tmrBackLightOn != NULL) {
				if(_display_flag_on < 2) {
					*_tmrBackLightOn = _val;
				}

				if(_display_flag_on == 0) {
					_display_flag_on = 1;
					_funcTurnBackLightOn = &prvTurnOnBackLight;
					vTimer500msFuncReg(_funcTurnBackLightOn, (void *)_tmrBackLightOn);
				}
			}
		break;

		case iOFF:
			/* Turn LCD Back Light OFF via Timer. */
			if(_tmrBackLightOff == NULL) {
				/* Obtain Timer. */
				_tmrBackLightOff = vTimer500msTake();
			}

			if(_tmrBackLightOff != NULL) {
				if(_display_flag_off < 2) {
					*_tmrBackLightOff = _val;
				}

				if(_display_flag_off == 0) {
					_display_flag_off = 1;
					_funcTurnBackLightOff = &prvTurnOffBackLight;
					vTimer500msFuncReg(_funcTurnBackLightOff, (void *)_tmrBackLightOff);
				}
			}
		break;

		default: break;
	}
}

/* -------------------------------------------------------------------------- */
static void prvTurnOnBackLight(void *_tmr)
{
	uint32_t *_ptr = _tmr;

	if(*_ptr == 0) {
		_display_flag_on = 2;
		/* Turn LCD Back Light On. */
		display_turn_backlight(iON);
		/* Unregister the function from list. */
		vTimer500msFuncUnreg(_funcTurnBackLightOn);
		/* Release Timers. */
		vTimer500msGive(_tmr);
	}
}

static void prvTurnOffBackLight(void *_tmr)
{
	uint32_t *_ptr = _tmr;

	if(*_ptr == 0) {
		_display_flag_off = 0;
		_display_flag_on = 0;
		/* Turn LCD Back Light Off. */
		display_turn_backlight(iOFF);
		/* Unregister the function from list. */
		vTimer500msFuncUnreg(_funcTurnBackLightOff);
		/* Release Timers. */
		vTimer500msGive(_tmr);
	}
}
